package com.rad.datastat.utils;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import android.Manifest.permission;
import android.R.anim;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

public class Utils {
	protected static final String TAG = Utils.class.getName();
	protected static final String b = "Unknown";
	private static final String GPRS = "gprs";
	private static final String WIFI = "wifi";
	public static final int DEFAULT_TIMEZOME = 8;

	public static boolean isPackageExist(String name, Context context) {
		PackageManager pm = context.getPackageManager();
		boolean exist = false;
		try {
			pm.getPackageInfo(name, 1);
			exist = true;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
			exist = false;
		}
		return exist;
	}

	public static String getModelName() {
		return android.os.Build.MODEL;
	}

	public static String getBrand() {
		return android.os.Build.BRAND;
	}

	public static String getOSVersion() {
		return android.os.Build.VERSION.RELEASE;
	}

	public static boolean isInChina(Context context) {
		Locale locale = context.getResources().getConfiguration().locale;
		return locale.toString().equals(Locale.CHINA.toString());
	}

	public static boolean isPortrait(Context context) {
        return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
    }

	public static String getVersionCode(Context context) {
		try {
			PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);

			int i = pi.versionCode;
			return String.valueOf(i);
		} catch (NameNotFoundException ex) {
			ex.printStackTrace();
		}
		return "Unknown";
	}

	public static String getVersionName(Context context) {
		try {
			PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
			return pi.versionName;
		} catch (NameNotFoundException ex) {
			ex.printStackTrace();
		}
		return "Unknown";
	}

	public static boolean checkPermission(Context context, String permission) {
		PackageManager pm = context.getPackageManager();
        return pm.checkPermission(permission, context.getPackageName()) == 0;
    }

	public static String getApplicationName(Context context) {
		PackageManager pm = context.getPackageManager();
		ApplicationInfo ai;
		try {
			ai = pm.getApplicationInfo(context.getPackageName(), 0);
		} catch (NameNotFoundException ex) {
			ex.printStackTrace();
			ai = null;
		}
		String name = (ai != null) ? pm.getApplicationLabel(ai).toString() : "";
		return name;
	}

	public static String getIMSI(Context context) {
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getSubscriberId();
	}

	public static String getIMEI(Context context) {
		TelephonyManager tm = (TelephonyManager) context.getSystemService("phone");

		if (tm == null) {
			Log.e(TAG, "No IMEI.");
		}

		String str = "";
		try {
			if (checkPermission(context, permission.READ_PHONE_STATE)) {
				str = tm.getDeviceId();
			}
		} catch (Exception ex) {
			Log.e(TAG, "No IMEI.", ex);
		}

		if (TextUtils.isEmpty(str)) {
			Log.e(TAG, "No IMEI.");
			str = getMacAddress(context);
			if (TextUtils.isEmpty(str)) {
				Log.w(TAG, "Failed to take mac as IMEI. Try to use Secure.ANDROID_ID instead.");
				str = Settings.Secure.getString(context.getContentResolver(), "android_id");
				Log.w(TAG, "getDeviceId: Secure.ANDROID_ID: " + str);
				return str;
			}
		}
		return str;
	}

	public static String j(Context context) {
		try {
			DisplayMetrics dm = new DisplayMetrics();
			WindowManager wm = (WindowManager) context.getSystemService("window");

			wm.getDefaultDisplay().getMetrics(dm);

			int i = dm.widthPixels;
			int j = dm.heightPixels;

			return String.valueOf(j) + "*" + String.valueOf(i);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return "Unknown";
	}

	public static boolean isWap(Context c) {
		ConnectivityManager manager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netWrokInfo = manager.getActiveNetworkInfo();

		if (netWrokInfo == null) {
			return false;
		}

		String typeName = netWrokInfo.getTypeName();
		String extraInfo = netWrokInfo.getExtraInfo();

        return "MOBILE".equalsIgnoreCase(typeName)
                && ("cmwap".equalsIgnoreCase(extraInfo) || "3gwap".equalsIgnoreCase(extraInfo)
                || "uniwap".equalsIgnoreCase(extraInfo) || "ctwap".equalsIgnoreCase(extraInfo));
	}

	public static String[] getNetworkInfo(Context context) {
		String[] ss = { "Unknown", "Unknown" };
		PackageManager pm = context.getPackageManager();
		if (pm.checkPermission(permission.ACCESS_NETWORK_STATE, context.getPackageName()) != 0) {
			ss[0] = "Unknown";
			return ss;
		}

		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

		if (cm == null) {
			ss[0] = "Unknown";
			return ss;
		}
		NetworkInfo ni1 = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

		if (ni1 != null && ni1.getState() == NetworkInfo.State.CONNECTED) {
			ss[0] = WIFI;
			return ss;
		}
		NetworkInfo ni2 = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

		if (ni2 != null && ni2.getState() == NetworkInfo.State.CONNECTED) {
			ss[0] = GPRS;
			ss[1] = ni2.getSubtypeName();
			return ss;
		}

		return ss;
	}

	public static boolean isGprs(Context context) {
		return GPRS.equals(getNetworkInfo(context)[0]);
	}

	public static boolean isWiFi(Context context) {
		return "wifi".equals(getNetworkInfo(context)[0]);
	}

	public static Location getCurrentLocation(Context context) {
		LocationManager lm = null;
		try {
			lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
			Location location;
			if (checkPermission(context, permission.ACCESS_FINE_LOCATION)) {
				location = lm.getLastKnownLocation("gps");

				if (location != null) {
					Log.w(TAG, "get location from gps:" + location.getLatitude() + "," + location.getLongitude());
					return location;
				}
			}

			if (checkPermission(context, permission.ACCESS_COARSE_LOCATION)) {
				location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
				if (location != null) {
					Log.w(TAG, "get location from network:" + location.getLatitude() + "," + location.getLongitude());

					return location;
				}
			}

			Log.w(TAG,
					"Could not get location from GPS or Cell-id, lack ACCESS_COARSE_LOCATION or ACCESS_COARSE_LOCATION permission?");

			return null;
		} catch (Exception ex) {
			Log.w(TAG, ex.getMessage());
		}
		return null;
	}

	public static boolean isNetworkConnected(Context context) {
		try {
			ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

			NetworkInfo ni = cm.getActiveNetworkInfo();
			if (ni == null) {
				return false;
			}
			return NetworkInfo.State.CONNECTED == ni.getState();
		} catch (Exception ex) {
			Log.e(TAG, "isNetworkConnected failed " + (ex == null ? "" : ex.getMessage()));
		}
		return false;
	}

	public static boolean isExternalStorageMounted() {
        return Environment.getExternalStorageState().equals("mounted");
    }

	public static int getTimeZone(Context context) {
		try {
			Locale locale = getLocale(context);
			Calendar cal = Calendar.getInstance(locale);
			if (cal != null)
				return cal.getTimeZone().getRawOffset() / 3600000;
		} catch (Exception ex) {
			Log.w(TAG, "error in getTimeZone", ex);
		}
		return DEFAULT_TIMEZOME;
	}

	public static String[] getLocaleInfo(Context context) {
		String[] ss = new String[2];
		try {
			Locale locale = getLocale(context);

			if (locale != null) {
				ss[0] = locale.getCountry();
				ss[1] = locale.getLanguage();
			}

			if (TextUtils.isEmpty(ss[0]))
				ss[0] = "Unknown";
			if (TextUtils.isEmpty(ss[1])) {
				ss[1] = "Unknown";
			}
			return ss;
		} catch (Exception ex) {
			Log.w(TAG, "error in getLocaleInfo", ex);
		}

		return ss;
	}

	private static Locale getLocale(Context context) {
		Locale locale = null;
		try {
			Configuration localConfiguration = new Configuration();
			Settings.System.getConfiguration(context.getContentResolver(), localConfiguration);

			if (localConfiguration != null)
				locale = localConfiguration.locale;
		} catch (Exception ex) {
			Log.w(TAG, "fail to read user config locale");
		}

		if (locale == null) {
			locale = Locale.getDefault();
		}

		return locale;
	}

	public static String getMacAddress(Context context) {
		try {
			WifiManager localWifiManager = (WifiManager) context.getSystemService("wifi");
			if (checkPermission(context, permission.ACCESS_WIFI_STATE)) {
				WifiInfo localWifiInfo = localWifiManager.getConnectionInfo();
				return localWifiInfo.getMacAddress();
			}
			Log.e(TAG, "Could not get mac address.[no permission android.permission.ACCESS_WIFI_STATE");
		} catch (Exception ex) {
			Log.e(TAG, "Could not get mac address." + ex.toString());
		}
		return "";
	}

	/**
	 * 获取屏幕大小
	 * 
	 * @param context
	 * @return example:width * height
	 */
	public static String getScreenSize(Context context) {
		try {
			DisplayMetrics dm = new DisplayMetrics();
			WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

			wm.getDefaultDisplay().getMetrics(dm);

			int i = -1;
			int j = -1;

			if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) == 0) {
				i = getDisplayMetricsFieldValue(dm, "noncompatWidthPixels");
				j = getDisplayMetricsFieldValue(dm, "noncompatHeightPixels");
			}

			if ((i == -1) || (j == -1)) {
				i = dm.widthPixels;
				j = dm.heightPixels;
			}

			StringBuffer sb = new StringBuffer();
			sb.append(i);
			sb.append("*");
			sb.append(j);

			return sb.toString();
		} catch (Exception ex) {
			Log.w(TAG, "read resolution fail", ex);
		}
		return "Unknown";
	}

	private static int getDisplayMetricsFieldValue(Object obj, String name) {
		try {
			Field field = DisplayMetrics.class.getDeclaredField(name);
			field.setAccessible(true);
			return field.getInt(obj);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return -1;
	}

	/**
	 * 获取运营商名称
	 * 
	 * @param context
	 * @return
	 */
	public static String getCarrier(Context context) {
		try {
			return ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getNetworkOperatorName();
		} catch (Exception ex) {
			Log.w(TAG, "read carrier fail", ex);
		}
		return "Unknown";
	}

	/**
	 * @param date1
	 * @param date2
	 * @return 返回 date2-date1 相隔的秒数的绝对值
	 */
	public static long getTimeDistance(Date date1, Date date2) {
		if (date1.after(date2)) {
			Date tmp = date1;
			date1 = date2;
			date2 = tmp;
		}

		return (date2.getTime() - date1.getTime()) / 1000L;
	}

	public static String getPackageName(Context context) {
		return context.getPackageName();
	}

	public static boolean isDebugable(Context context) {
		try {
			return (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return false;
	}

	/**
	 * 
	 * @return MB结尾的单位。如：1024MB
	 */
	public static String getExternalStorageSize() {
		// 判断是否有插入存储卡
		if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			File path = Environment.getExternalStorageDirectory();
			StatFs statfs = new StatFs(path.getPath());
			long blocSize = statfs.getBlockSize();
			long totalBlocks = statfs.getBlockCount();

			return convertSizeToMB(totalBlocks * blocSize);
		} else if (Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED)) {
			return "0MB";
		} else {
			return "0MB";
		}
	}

	private static String convertSizeToMB(long size) {
		if (size > 1024 * 1024) {
			return (size / 1024 / 1024) + "MB";
		} else {
			return "0MB";
		}
	}

	public static boolean isScreenLocked(Context mContext) {
		KeyguardManager mgr = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
		return mgr.inKeyguardRestrictedInputMode();
	}

	// 获取andooidID
	public static String getAndroidId(Context context) {
		return android.provider.Settings.Secure.getString(context.getContentResolver(),
				android.provider.Settings.Secure.ANDROID_ID);
	}
}